static TEST_LOGGER: TestLogger = TestLogger::new();
pub(crate) fn init_logger() {
    _ = log::set_logger(&TEST_LOGGER);
    log::set_max_level(log::LevelFilter::Trace);
}

pub(crate) fn build_async_runtime(action: impl std::future::Future) {
    tokio::runtime::Builder::new_multi_thread()
        .worker_threads(4)
        .enable_all()
        .build()
        .unwrap()
        .block_on(action);
}

pub struct TestLogger {}

impl TestLogger {
    const fn new() -> Self {
        Self {}
    }
}

impl log::Log for TestLogger {
    fn enabled(&self, _: &log::Metadata) -> bool {
        return true;
    }

    fn log(&self, record: &log::Record) {
        let level = record.level();
        let cur = chrono::Local::now().format("%Y-%m-%d %H:%M:%S.%3f");
        if level <= log::Level::Error {
            println!(
                "{cur} {level} file = {}, mod = {}, line = {}, {}",
                record.file().unwrap_or("unknow"),
                record.target(),
                record.line().unwrap_or(0),
                record.args().to_string()
            );
        } else {
            println!("{cur} {level} {}", record.args().to_string());
        }
    }

    fn flush(&self) {}
}
